﻿using System;
using System.Globalization;
using System.Linq;
using System.Net.Mail;
using System.Web.Mvc;
using System.Web.Routing;
using Diploma.Models;
using DiplomaWeb.Configuration;
using DiplomaWeb.Models.Account;
using ViewRes;

namespace DiplomaWeb.Controllers
{
    public class AccountController : MasterController
    {
        public AccountController(DataManager dataManager) : base(dataManager)
        {
        }

        #region Public

        public ActionResult LogOn()
        {
            if (Request.IsAuthenticated)
            {
                return ToPage();
            }
            return View();
        }

        [HttpPost]
        public ActionResult LogOn(LogOnViewModel model, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                if (MembershipService.ValidateUser(model.UserName, model.Password))
                {
                    if (Configuration.Settings.VerifyStep)
                    {
                        Session["userEmail"] = model.UserName;
                        SendHashToUser(model.UserName);
                        LoggerInfo("LogOn is Ok. Email has sent.");
                        return RedirectToRoute("Default", new {action = "Verification", controller = "Account"});
                    }
                    else
                    {
                        FormsService.SignIn(model.UserName);
                        SignUpInSystem(model.UserName);
                        return ToPage();
                    }
                }
                LoggerInfo("LogOn is Fail");
                ModelState.AddModelError("", AccountStrings.AccountController_LogOn_EmailAndPassword_Incorrect);
            }

            return View(model);
        }
        
        public ActionResult Verification()
        {
            var userName = Session["userEmail"];
            Session.Remove("userEmail");
            if (userName == null)
            {
                return RedirectToRoute("Default", new { action = "LogOn", controller = "Account" });
            }

            if (!(userName is String))
            {
                return RedirectToRoute("Default", new { action = "LogOn", controller = "Account" });
            }

            return View(new VerificationViewModel { UserName = (String)userName });
        }

        [HttpPost]
        public ActionResult Verification(VerificationViewModel model)
        {
            if (ModelState.IsValid && DataManager.UsersRepository.ValidateUserHash(model.UserName, model.Hash))
            {
                FormsService.SignIn(model.UserName);
                SignUpInSystem(model.UserName);
                return ToPage();
            }

            LoggerInfo("Verification has finished with fail status.");
            return RedirectToRoute("Default", new { action = "LogOn", controller = "Account" });
        }

        public ActionResult LogOff()
        {
            FormsService.SignOut();

            return RedirectToRoute("Default", new {controller = "Account", action = "LogOn",});
        }

        public ActionResult ChangeCulture(string lang, string returnUrl)
        {
            Session["Culture"] = new CultureInfo(lang);
            return Redirect(returnUrl);
        }

        [Authorize]
        public ActionResult ToPage()
        {
            return RedirectUserToCorrespondingPage(User.Identity.Name);
        }

        public ActionResult UpdatePasswords()
        {
            if(Configuration.Settings.CanUpdatePasswords)
            {
                var users = DataManager.UsersRepository.GetUsers();
                foreach (User user in users)
                {
                    DataManager.UsersRepository.UpdatePassword(user.UserId, user.Password);
                }
            }

            return RedirectToRoute("Default", new {controller = "Account", action = "LogOn",});
        }

        #endregion

        #region Private

        private ActionResult RedirectUserToCorrespondingPage(string username)
        {
            User loggedUser = DataManager.UsersRepository.GetUserByEmail(username, false);
            var result = RedirectToRoute("Default", new {controller = "Account", action = "LogOn",});

            if (loggedUser is Student)
                result = RedirectToRoute("Default", new { controller = "Students", action = "News", });

            if (loggedUser is Lecturer)
                result = RedirectToRoute("Default", new { controller = "Lecturers", action = "News", });

            if (loggedUser is Administrator)
                result = RedirectToRoute("Default", new { controller = "Administrators", action = "News", });

            if (loggedUser is SystemManager)
                result = RedirectToRoute("Default", new { controller = "SystemManagers", action = "News", });

            if (loggedUser is DepartmentHead)
                result = RedirectToRoute("Default", new { controller = "DepartmentHeads", action = "Home", });

            if (loggedUser is Developer)
                result = RedirectToRoute("Default", new { controller = "Developer", action = "Home", });

            if (loggedUser is Reviewer)
                result = RedirectToRoute("Default", new { controller = "Reviewer", action = "Index", });

            return result;
        }

        private void SendHashToUser(string userName)
        {
            var hash = DataManager.UsersRepository.GenerateHash(userName);
            var mailClient = new SmtpClient();

            if (Configuration.Settings.UseTestEmail)
            {
                mailClient.Send("diplom-pi@mail.ru", Configuration.Settings.TestLogOnEmail, "Account LogOn Verification",
                                String.Format("The Hash code is: {0}", hash));
            }
            else
            {
                mailClient.Send("diplom-pi@mail.ru", userName, "Account LogOn Verification",
                                String.Format("The Hash code is: {0}", hash));
            }
        }

        #endregion
    }
}